/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package parser.part.n2;

import java.awt.Point;
import java.util.HashMap;
import java.util.List;

/**
 *
 * @author Patronus
 */
public class Worker {

    private List ourTree;
    private HashMap<String, Point> HM = new HashMap<String, Point>();
    private HashMap<String, Object> results = new HashMap<String, Object>();
    private List hor;

    Worker(List ls) {
        this.ourTree = ls;
    }
//исполнитель 

    public HashMap justDoIt() {
        HM = getMap();
        Object res;
        hor = null;
        for (int vertical = 0; vertical < ourTree.size(); vertical++) {
            hor = (List) ourTree.get(vertical);
            for (int horisontal = 0; horisontal < hor.size(); horisontal++) {
                Ruler oneRule = (Ruler) hor.get(horisontal);
                if (!needFill(oneRule)) {
                    res = oneRule.exequteRule();

                } else {
                    res = fillAndExecute(oneRule);
                }
                if (oneRule.getReturnResult()) {
                    putResult(oneRule, res, horisontal);
                }
            }
            ourTree.set(vertical, hor);
        }


        return results;
    }
//есть ли в правиле поля необходимые импортировать откудато

    private boolean needFill(Ruler rule) {
        Object connections[][] = rule.getImport();
        for (int i = 0; i < connections.length; i++) {
            if (connections[i][0] != null) {
                return true;
            }
        }

        return false;
    }
    //проверка является ли параметр правилом , если да то исполнить
    //и заполнить поле, если нет, то только заполнить поле

    private Object fillAndExecute(Ruler rule) {
        Object[][] imp = rule.getImport();
        for (int i = 0; i < imp.length; i++) {
            if (imp[i][0] != null) {
                String id = (String) imp[i][0];
                Point p = HM.get(id);
                List horLine = (List) ourTree.get((int) p.getY());
                Object param = horLine.get((int) p.getX());
                for (Object t : param.getClass().getSuperclass().getInterfaces()) {
                    if (t.toString().indexOf("Rule") != -1) {
                        param = fillAndExecute((Ruler) param);
                    }
                }
                rule.setArgs(i, param);
            }
        }


        return rule.exequteRule();
    }

    //Возвращает хешмеп для поиска правила в таблице по его ID
    private HashMap getMap() {

        for (int vertical = 0; vertical < ourTree.size(); vertical++) {
            List horisontalLocal = (List) ourTree.get(vertical);
            for (int horisontal = 0; horisontal < horisontalLocal.size(); horisontal++) {
                Ruler oneRule = (Ruler) horisontalLocal.get(horisontal);
                HM.put(oneRule.getId(), new Point(horisontal, vertical));
            }
            ourTree.set(vertical, horisontalLocal);
        }
        return this.HM;
    }

    private void putResult(Ruler rule, Object res, int horisontal) {
        hor.set(horisontal, res);
        if (rule.getReturnResult()) {
            results.put(rule.getId(), res);
        }
    }

    public void setTree(List s) {

        this.ourTree = s;
    }
}
